<template>
  <q-card id="comment" class="q-mt-sm">
    <q-card-section>
      <div class="font-semibold text-lg q-pb-md">发布评论</div>
      <SendComment
        @add-comment="
          (data) => {
            comments.unshift(data);
            commentsNum = commentsNum + 1;
          }
        "
      ></SendComment>
    </q-card-section>
    <q-card-section>
      <div class="font-semibold text-lg">全部评论({{ commentsNum }})</div>
      <div v-if="comments.length == 0" class="flex justify-center items-center">
        <div class="text-h6 q-pa-sm">此时无声胜有声~</div>
      </div>
      <q-item class="q-pa-none q-py-sm" v-for="item in comments" :key="item.id">
        <q-item-section top avatar>
          <q-avatar>
            <q-img
              :src="item.userInfo.avatar"
              errorSrc="/images/default-avatar.png"
              :ratio="1 / 1"
            />
          </q-avatar>
        </q-item-section>
        <q-item-section>
          <q-item-label>
            <RouterLink
              class="decoration-none"
              :to="{
                path: '/personal/' + item.userInfo.id + '/create',
              }"
            >
              <span class="text-sm text-slate-600 hover:text-blue-500">
                {{ item.userInfo.username }}
              </span>
            </RouterLink>

            <span class="q-pl-sm text-slate-400">{{ item.address }}</span>
          </q-item-label>
          <q-item-label>
            <div v-html="item.content"></div>
          </q-item-label>
          <q-item-label>
            <div class="row" v-if="webStore.isLogin">
              <div class="col row items-center text-slate-500">
                <div class="text-sm">{{ item.relativeTime }}</div>
                <q-btn
                  :icon="item.likedFlag ? 'favorite' : 'favorite_border'"
                  :color="item.likedFlag ? 'primary' : ''"
                  dense
                  flat
                  size="sm"
                  @click="
                    () => {
                      likedClick(item);
                    }
                  "
                >
                  <div class="text-sm q-pl-xs">点赞 {{ item.likes }}</div>
                </q-btn>

                <q-btn
                  dense
                  flat
                  icon="comment"
                  :color="item.replyStatus ? 'primary' : ''"
                  size="sm"
                  @click="
                    () => {
                      item.replyStatus = !item.replyStatus;
                      nextTick(() => {
                        editorRef[item.id].focus();
                      });
                    }
                  "
                >
                  <div class="text-sm q-pl-xs">回复</div>
                </q-btn>
              </div>
              <div class="row items-center">
                <q-icon name="fa-solid fa-ellipsis-vertical">
                  <CommentOperate
                    :item="item"
                    @copy="
                      () => {
                        copyComment(item);
                      }
                    "
                    @del="
                      () => {
                        removeComment(item);
                      }
                    "
                    @report="
                      () => {
                        reportDig = true;
                        reportInfo.commentId = item.id;
                      }
                    "
                  ></CommentOperate>
                </q-icon>
              </div>
            </div>
            <div v-show="item.replyStatus" class="q-pt-xs">
              <q-editor
                :ref="
                  (el) => {
                    editorRef[item.id] = el;
                  }
                "
                @keyup.ctrl.enter.stop="
                  () => {
                    replItem(item);
                  }
                "
                :toolbar="[]"
                v-model="item.replyComment"
                min-height="5rem"
              />
              <div class="flex justify-between q-pt-xs">
                <div class="flex items-center">
                  <q-btn dense flat icon="emoji_emotions">
                    <EmojiSel
                      @emoji-click="
                        (emoji) => {
                          item.replyComment += emoji;
                        }
                      "
                    ></EmojiSel>
                    <q-tooltip> 表情 </q-tooltip>
                  </q-btn>
                </div>
                <div class="text-grey-5">文明交流，友好发言..</div>
                <div>
                  <q-btn
                    @click="
                      () => {
                        replItem(item);
                      }
                    "
                    :disable="item.replyComment.length == 0"
                    dense
                    color="primary"
                  >
                    <span class="q-mx-sm">回复</span>
                  </q-btn>
                </div>
              </div>
            </div>
            <div v-show="item.replyData.total">
              <q-item
                v-for="rep in item.replyData.list"
                class="q-pa-none q-pt-sm"
                :key="rep.id"
              >
                <q-item-section top avatar>
                  <q-avatar>
                    <q-img
                      :src="rep.userInfo.avatar"
                      errorSrc="/images/default-avatar.png"
                      :ratio="1 / 1"
                    />
                  </q-avatar>
                </q-item-section>
                <q-item-section>
                  <q-item-label>
                    <RouterLink
                      class="decoration-none"
                      :to="{
                        path: '/personal/' + rep.userInfo.id + '/create',
                      }"
                    >
                      <span class="text-sm text-slate-600 hover:text-blue-500">
                        {{ rep.userInfo.username }}
                      </span>
                    </RouterLink>
                    <span class="q-pl-sm text-slate-400">
                      {{ rep.address }}
                    </span>
                  </q-item-label>
                  <q-item-label>
                    <div v-if="rep.preCmt" class="row">
                      回复
                      <div class="text-primary q-px-xs">
                        {{ rep.preCmt.username }}
                        <q-tooltip class="bg-white text-sm text-gray-7 row">
                          <div class="text-primary">
                            {{ rep.preCmt.username }}
                          </div>
                          :
                          <div
                            class="q-pl-xs"
                            v-html="rep.preCmt.content"
                          ></div>
                        </q-tooltip>
                      </div>
                      <div v-html="rep.content"></div>
                    </div>
                    <div v-else v-html="rep.content"></div>
                  </q-item-label>
                  <q-item-label>
                    <div class="row justify-between" v-if="webStore.isLogin">
                      <div class="row items-center text-slate-500">
                        <div class="text-sm">{{ rep.relativeTime }}</div>
                        <q-btn
                          :icon="rep.likedFlag ? 'favorite' : 'favorite_border'"
                          :color="rep.likedFlag ? 'primary' : ''"
                          dense
                          flat
                          size="sm"
                          @click="
                            () => {
                              likedClick(rep);
                            }
                          "
                        >
                          <div class="text-sm q-pl-xs">
                            点赞 {{ rep.likes }}
                          </div>
                        </q-btn>

                        <q-btn
                          dense
                          flat
                          icon="comment"
                          :color="rep.replyStatus ? 'primary' : ''"
                          size="sm"
                          @click="
                            () => {
                              rep.replyStatus = !rep.replyStatus;
                              nextTick(() => {
                                editorRef[rep.id].focus();
                              });
                            }
                          "
                        >
                          <div class="text-sm q-pl-xs">回复</div>
                        </q-btn>
                      </div>
                      <div>
                        <q-icon name="fa-solid fa-ellipsis-vertical">
                          <CommentOperate
                            :item="rep"
                            @copy="
                              () => {
                                copyComment(rep);
                              }
                            "
                            @del="
                              () => {
                                Confirm('确认删除此评论?', () => {
                                  removeReplyComment(rep).then(
                                    ({ data, error }) => {
                                      if (error) {
                                        return;
                                      }
                                      commentsNum = commentsNum - data;
                                      item.replyData.list =
                                        item.replyData.list.filter(
                                          (i) => i.id != rep.id,
                                        );
                                      Ok('删除成功');
                                    },
                                  );
                                });
                              }
                            "
                            @report="
                              () => {
                                reportDig = true;
                                reportInfo.commentId = item.id;
                              }
                            "
                          ></CommentOperate>
                        </q-icon>
                      </div>
                    </div>
                    <div v-show="rep.replyStatus" class="q-pt-sm">
                      <q-editor
                        :ref="
                          (el) => {
                            editorRef[rep.id] = el;
                          }
                        "
                        @keyup.ctrl.enter.stop="
                          () => {
                            replRep(rep, item);
                          }
                        "
                        :toolbar="[]"
                        v-model="rep.replyComment"
                        min-height="5rem"
                      />
                      <div class="row q-py-sm">
                        <q-btn dense flat icon="emoji_emotions">
                          <EmojiSel
                            @emoji-click="
                              (emoji) => {
                                rep.replyComment += emoji;
                              }
                            "
                          ></EmojiSel>
                          <q-tooltip> 表情 </q-tooltip>
                        </q-btn>
                        <div class="text-grey-10 col row justify-center">
                          <q-item
                            clickable
                            dense
                            :to="{
                              path: '/personal/' + rep.userInfo.id + '/create',
                            }"
                          >
                            <div class="row items-center">
                              <div>
                                回复:
                                <span class="text-primary">{{
                                  rep.userInfo.username
                                }}</span>
                              </div>
                            </div>
                          </q-item>
                        </div>
                        <q-btn
                          @click="
                            () => {
                              replRep(rep, item);
                            }
                          "
                          :disable="rep.replyComment.length == 0"
                          dense
                          color="primary"
                        >
                          <span class="q-mx-sm">回复</span>
                        </q-btn>
                      </div>
                    </div>
                  </q-item-label>
                </q-item-section>
              </q-item>
              <div class="row q-pt-sm">
                <q-pagination
                  size="10px"
                  v-model="item.replyData.pageNum"
                  @update:model-value="
                    (val) => {
                      item.replyData.pageNum = val;
                      replyPage(item);
                    }
                  "
                  :max="item.replyData.totalPage"
                  :max-pages="6"
                  boundary-numbers
                  direction-links
                />
                <q-chip clickable dense square :label="item.replyData.pageSize">
                  <q-menu>
                    <div
                      @click="
                        () => {
                          item.replyData.pageSize = sel;
                          replyPage(item);
                        }
                      "
                      v-close-popup
                      class="q-pa-sm cursor-pointer hover:bg-lightBlue-2"
                      v-for="sel in [10, 20, 40, 100]"
                      :key="sel"
                    >
                      {{ sel }}
                    </div>
                  </q-menu>
                  <q-tooltip> 一页显示几条评论 </q-tooltip>
                </q-chip>
              </div>
            </div>
          </q-item-label>
        </q-item-section>
      </q-item>
    </q-card-section>
    <q-card-section class="flex justify-center">
      <q-btn
        :disable="
          pageParam.recordCount == 0 || pageParam.pageNum == pageParam.totalPage
        "
        color="primary"
        flat
        @click="
          () => {
            if (pageParam.pageNum != pageParam.totalPage) {
              pageParam.pageNum++;
              load();
            }
          }
        "
      >
        <span class="q-mx-sm">
          {{
            pageParam.pageNum >= pageParam.totalPage ? '已加载全部' : '加载更多'
          }}
        </span>
      </q-btn>
    </q-card-section>

    <q-dialog
      v-model="reportDig"
      @hide="
        () => {
          reportInfo = {
            commentId: '',
            remark: '',
          };
        }
      "
    >
      <q-card style="min-width: 350px">
        <q-card-section>
          <div class="text-h6">举报原因</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          <q-input
            dense
            v-model="reportInfo.remark"
            autofocus
            @keyup.enter="
              () => {
                reportCommentFn();
              }
            "
          />
        </q-card-section>

        <q-card-actions align="right" class="text-primary">
          <q-btn flat label="关闭" v-close-popup />
          <q-btn
            flat
            label="确认"
            @click="
              () => {
                reportCommentFn();
              }
            "
            v-close-popup
          />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </q-card>
</template>

<script setup lang="ts">
import { nextTick, onMounted, ref } from 'vue';
import {
  commentAdd,
  commentDel,
  commentLiked,
  commentList,
  commentReply,
  commentReport,
} from 'src/service/api';
import { replaceText, useYuan } from 'src/use';
import { copyToClipboard, throttle } from 'quasar';
import { watch } from 'vue';
import EmojiSel from './EmojiSel.vue';
import SendComment from './SendComment.vue';
import CommentOperate from './CommentOperate.vue';
import { useWebStore } from 'src/stores/webStore';
import { commentsNum, articleId } from './shared';

const webStore = useWebStore();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const editorRef = ref<{ [key: string]: any }>({});
watch(
  () => articleId.value,
  () => {
    pageParam.value.pageNum = 1;
    comments.value = [];
    load();
  },
);
const comments = ref<Array<Api.CommentVO>>([]);
const { Ok, Confirm, Fail } = useYuan();

const reportDig = ref(false);
const reportInfo = ref({
  commentId: '',
  remark: '',
});

const reportCommentFn = async () => {
  if (reportInfo.value.remark == '') {
    Fail('举报原因不可为空');
    return;
  }
  const { error } = await commentReport(reportInfo.value);
  reportDig.value = false;
  if (!error) {
    Ok('举报成功，处理结果将在一定时间内通知你~');
  }
};

// 回复评论
const replySubmit = (comment: Api.CommentVO) => {
  return commentAdd({
    articleId: articleId.value,
    content: comment.replyComment,
    parentId: comment.parentId,
    replyId: comment.id,
  });
};

const replItem = (item: Api.CommentVO) => {
  if (item.replyComment.trim().length == 0) {
    return Fail('评论内容不可为空');
  }
  item.parentId = item.id;
  replySubmit(item).then(({ error }) => {
    if (error) {
      return;
    }
    commentsNum.value = commentsNum.value + 1;
    replyPage(item);
    item.replyStatus = false;
    item.replyComment = '';
    Ok('回复成功');
  });
};

const replRep = throttle((rep: Api.CommentVO, item: Api.CommentVO) => {
  if (rep.replyComment.trim().length == 0) {
    return Fail('评论内容不可为空');
  }
  rep.parentId = item.id;
  replySubmit(rep).then(({ error }) => {
    if (error) {
      return;
    }
    commentsNum.value = commentsNum.value + 1;
    replyPage(item);
    rep.replyStatus = false;
    rep.replyComment = '';
    Ok('回复成功');
  });
}, 500);

const replyPage = (item: Api.CommentVO) => {
  commentReply({
    pageNum: item.replyData.pageNum,
    parentId: item.id,
    pageSize: item.replyData.pageSize,
  }).then(({ error, data }) => {
    if (!error) {
      item.replyData.list = data.rows;
      item.replyData.pageNum = data.pageNum;
      item.replyData.pageSize = data.pageSize;
      item.replyData.total = data.recordCount;
      item.replyCount = item.replyData.total;
      item.replyData.totalPage = data.totalPage;
    }
  });
};

// 复制评论
const copyComment = (comment: Api.CommentVO) => {
  copyToClipboard(replaceText(comment.content)).then(() => {
    Ok('复制成功 ');
  });
};
// 删除评论
const removeComment = (comment: Api.CommentVO) => {
  Confirm('确认删除此评论？', async () => {
    const { data, error } = await commentDel({ id: comment.id });
    if (error) {
      return;
    }
    commentsNum.value = commentsNum.value - data;
    comments.value = comments.value.filter((i) => i.id != comment.id);
    Ok('评论删除成功');
  });
};
const removeReplyComment = (comment: Api.CommentVO) => {
  return commentDel({ id: comment.id });
};

const likedClick = async (item: Api.CommentVO) => {
  const { error, data } = await commentLiked({ commentId: item.id });
  if (error) {
    return;
  }
  if (data) {
    item.likedFlag = true;
    item.likes += 1;
    Ok('点赞成功');
  } else {
    item.likedFlag = false;
    item.likes -= 1;
    Ok('已取消点赞');
  }
};

const pageParam = ref({
  pageNum: 1,
  pageSize: 7,
  totalPage: 0,
  recordCount: 0,
});
const load = () => {
  commentList({
    articleId: articleId.value,
    pageNum: pageParam.value.pageNum,
    pageSize: pageParam.value.pageSize,
  }).then(({ data, error }) => {
    if (!error) {
      comments.value.push(...data.rows);
      pageParam.value.recordCount = data.recordCount;
      pageParam.value.totalPage = data.totalPage;
    }
  });
};

onMounted(() => {
  load();
});
</script>

<style lang="scss" scoped></style>
